home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / web / noweb / src / c / mnt.c < prev    next >
C/C++ Source or Header  |  1995-02-24  |  5KB  |  174 lines

  1. #line 8 "mnt.nw"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6. #include <ctype.h>
  7. #include "modules.h"
  8. #include "modtrees.h"
  9. #include "notangle.h"
  10. #include "errors.h"
  11. #include "columns.h"
  12. #include "strsave.h"
  13.  
  14. #line 47 "mnt.nw"
  15. void add_uses_to_usecounts(Module mp);
  16. void emit_if_unused_and_conforming(Module mp);
  17. #line 79 "mnt.nw"
  18. static void emitfile(char *modname);
  19. #line 174 "mnt.nw"
  20. #ifdef TEMPNAM
  21. extern char *tempnam (const char *dir, const char *pfx);        /* temp file in dir */
  22. #else
  23. #define tempnam(DIR,PFX) (strsave(tmpnam(NULL)))
  24. #endif
  25.  
  26. #line 22 "mnt.nw"
  27. #define Clocformat "#line %L \"%F\"%N"
  28. static char *locformat = Clocformat;
  29.  
  30. main(int argc, char **argv) {
  31.     int i;
  32.  
  33.     tabsize = 0;  /* default for nt is not to use tabs */
  34.  
  35.     
  36. #line 41 "mnt.nw"
  37. read_defs(stdin);
  38. apply_each_module(remove_final_newline);
  39. #line 31 "mnt.nw"
  40.     for (i=1; i<argc; i++) 
  41.       switch (*argv[i]) {
  42.         case '-': 
  43. #line 146 "mnt.nw"
  44.     switch (*++argv[i]) {
  45.         case 'a':
  46.             if (strcmp(argv[i], "all"))
  47.                 errormsg(Warning, "Ignoring unknown option -%s", argv[i]);
  48.             else {
  49. #line 44 "mnt.nw"
  50. apply_each_module(add_uses_to_usecounts);
  51. apply_each_module(emit_if_unused_and_conforming);
  52. #line 150 "mnt.nw"
  53.                                                     }
  54.             break;
  55.         case 't': /* set tab size or turn off */
  56.             if (isdigit(argv[i][1]))
  57.                 tabsize = atoi(argv[i]+1);
  58.             else if (argv[i][1]==0)
  59.                 tabsize = 0;            /* no tabs */
  60.             else 
  61.                 errormsg(Error, "%s: ill-formed option %s\n", argv[0], argv[i]);
  62.             break;          
  63.         case 'L': /* have a #line number format */
  64.             locformat = argv[i] + 1;
  65.             if (!*locformat) locformat = Clocformat;
  66.             break;
  67.         default:
  68.             errormsg(Warning, "Ignoring unknown option -%s", argv[i]);
  69.      }
  70. #line 33 "mnt.nw"
  71.                                                                    break;
  72.         default:  emitfile(argv[i]);                               break;
  73.       }
  74.     exit(errorlevel);
  75.     return errorlevel;          /* slay warning */
  76. }
  77. #line 50 "mnt.nw"
  78. void add_uses_to_usecounts(Module mp) {
  79.     Module used;
  80.     struct modpart *p;
  81.     for (p=mp->head; p!=NULL; p=p->next)
  82.         if (p->ptype == MODULE) {
  83.             used = lookup(p->contents);
  84.             if (used != NULL)
  85.                 used->usecount++;
  86.         }
  87. }
  88. #line 66 "mnt.nw"
  89. void emit_if_unused_and_conforming(Module mp) {
  90.     char *index;
  91.     if (mp->usecount == 0 && strpbrk(mp->name, " \n\t\v\r\f") == NULL)
  92.         if (index = strpbrk(mp->name, "[](){}!$&<>*?;|^`'\\\""),
  93.             index == NULL || index[0] == '*' && index[1] == 0)
  94.             emitfile(mp->name);
  95.         else 
  96.             errormsg(Error, "<<%s>> cannot be an output chunk; "
  97.                             "it contains a metacharacter", mp->name);
  98. }
  99. #line 81 "mnt.nw"
  100. static void emitfile(char *modname) { 
  101.   Module root = lookup(modname);
  102.   char *tempname = tempnam(".", 0);
  103.   FILE *fp;
  104.   char *lfmt, *filename;
  105.   
  106. #line 102 "mnt.nw"
  107. { int n = strlen(modname) - 1;
  108.   if (n >= 0 && modname[n] == '*') {
  109.     lfmt = locformat;
  110.     filename = strsave(modname);
  111.     filename[n] = 0;
  112.   } else {
  113.     lfmt = "";
  114.     filename = modname;
  115.   }
  116. }
  117. #line 87 "mnt.nw"
  118.   
  119. #line 141 "mnt.nw"
  120. if (root == NULL) {
  121.   errormsg(Error, "Chunk <<%s>> is undefined", filename);
  122.   return;
  123. }
  124. #line 88 "mnt.nw"
  125.   fp = fopen(tempname, "w");
  126.   if (fp == NULL) errormsg(Fatal, "Can't open temporary file %s", tempname);
  127.   
  128. #line 113 "mnt.nw"
  129. resetloc();
  130. (void) expand(root, 0, 0, 0, lfmt, fp);
  131. putc('\n', fp);
  132. fclose(fp);
  133. #line 91 "mnt.nw"
  134.   
  135. #line 119 "mnt.nw"
  136. { FILE *dest, *tmp;
  137.   dest = fopen(filename, "r");
  138.   if (dest != NULL) {
  139.     int x, y;
  140.     tmp = fopen(tempname, "r");
  141.     assert(tmp);
  142.     do { 
  143.       x = getc(tmp);
  144.       y = getc(dest);
  145.     } while (x == y && x != EOF);
  146.     fclose(tmp);
  147.     fclose(dest);
  148.     if (x == y) {
  149.       remove(tempname);
  150.       return;
  151.     }
  152.   }
  153. }
  154. #line 92 "mnt.nw"
  155.   remove(filename);
  156.   if (rename(tempname, filename) != 0) { /* different file systems? (may have to copy) */
  157.     FILE *fp = fopen(filename, "w");
  158.     if (fp == NULL) {remove(tempname); 
  159. #line 138 "mnt.nw"
  160. errormsg(Error, "Can't open output file %s", filename);
  161. return;
  162. #line 95 "mnt.nw"
  163.                                                                                      }
  164.     
  165. #line 113 "mnt.nw"
  166. resetloc();
  167. (void) expand(root, 0, 0, 0, lfmt, fp);
  168. putc('\n', fp);
  169. fclose(fp);
  170. #line 97 "mnt.nw"
  171.     remove(tempname);
  172.   }
  173. }
  174.